
TaskControl = function(spec) {
    this.spec = $.extend({}, spec);
    this.tasks = [];
    this.event = $({});
    var container = $(spec);
    container.append([
        '<ul class="task-control">',
        '<li class="add">',
        'at ',
        '<input class="time" type="text"/>',
        ' ',
        '<select class="action">',
        '<option value="buy">buy</option>',
        '<option value="meet">meet</option>',
        '</select>',
        ' ',
        '<input class="object" type="text"/>',
        ' at ',
        '<input class="location" type="text"/>',
        ' ',
        '<button class="link-button action-button">+</button>',
        '</li>',
        '</ul>'
    ].join(''));
    this.el = container.children(':last');

    this.taskId = 0;

    this.addSection = this.el.children('.add');
    this.addSection.children('button').click($.proxy(this.itemAdded, this));

    this.geocoder = new google.maps.Geocoder();

    this.addTaskImpl(Action.buy({ item: 'tomatoes' }));
    this.addTaskImpl(Action.buy({ item: 'dishware' }));
};

TaskControl.prototype = {
    itemAdded: function() {
        var location = this.addSection.children('.location').val();
        if (location) {
            this.geocoder.geocode({ address: location }, $.proxy(this.geocoderResult, this));
        } else {
            this.createTaskUsingLocation(null);
        }
    },

    geocoderResult: function(results, status) {
        if (status != google.maps.GeocoderStatus.OK) {
            throw 'fixme: work out errors';
        }

        var location = {
            address: results[0].formatted_address,
            lat: results[0].geometry.location.lat(),
            lng: results[0].geometry.location.lng()
        };

        this.createTaskUsingLocation(location);
    },

    createTaskUsingLocation: function(location) {
        var time = this.addSection.children('.time').val();
        var action = this.addSection.children('.action').val();
        var object = this.addSection.children('.object').val();

        var task = Action[action]({
            id: this.taskId++,
            time: time || null,
            item: object,
            entity: object,
            location: location
        });

        this.addTaskImpl(task);
    },

    addTaskImpl: function(task) {
        this.tasks.push(task);
        var time = task.time;
        var action = task.action;
        var object = task.item || task.entity;
        var location = task.location;

        var html = [
                '<li>',
                time ? ('at ' + time + ' ') : '',
                action,
                ' ',
                object,
                location ? (' at ' + location.address + ' ') : '',
                ' ',
                '<button class="link-button action-button">-</button>',
                '</li>'
        ];

        this.addSection.before(html.join(''));
        var li = this.el.children(':not(.add)').filter(':last');

        li.children('button').click($.proxy(this.deleteTask, this, task, li));
    },

    deleteTask: function(task, li) {
        var index = null;
        $.each(this.tasks, function(i, t) {
            if (t.id == task.id) {
                index = i;
                return false;
            }
        });

        if (index === null) {
            throw 'Invalid task ' + task;
        }

        this.tasks.splice(index, 1);
        li.remove();
    }
};
